package com.x.organization.assemble.express.jaxrs.identity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;

import com.google.gson.JsonElement;
import com.x.base.core.container.EntityManagerContainer;
import com.x.base.core.container.factory.EntityManagerContainerFactory;
import com.x.base.core.entity.JpaObject;
import com.x.base.core.project.annotation.FieldDescribe;
import com.x.base.core.project.cache.ApplicationCache;
import com.x.base.core.project.gson.GsonPropertyObject;
import com.x.base.core.project.http.ActionResult;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.tools.ListTools;
import com.x.organization.assemble.express.Business;
import com.x.organization.core.entity.Identity;
import com.x.organization.core.entity.Identity_;
import com.x.organization.core.entity.Person;

import net.sf.ehcache.Element;

class ActionListWithPersonObject extends BaseAction {

    ActionResult<List<Wo>> execute(EffectivePerson effectivePerson, JsonElement jsonElement) throws Exception {
        try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
            Wi wi = this.convertToWrapIn(jsonElement, Wi.class);
            ActionResult<List<Wo>> result = new ActionResult<>();
            Business business = new Business(emc);
            String cacheKey = ApplicationCache.concreteCacheKey(this.getClass(),
                    StringUtils.join(wi.getPersonList(), ","));
            Element element = cache.get(cacheKey);
            if (null != element && (null != element.getObjectValue())) {
                result.setData((List<Wo>) element.getObjectValue());
            } else {
                List<Wo> wos = this.list(business, wi);
                cache.put(new Element(cacheKey, wos));
                result.setData(wos);
            }
            return result;
        }
    }

    public static class Wi extends GsonPropertyObject {
        @FieldDescribe("个人")
        private List<String> personList = new ArrayList<>();
        public List<String> getPersonList() {
            return personList;
        }
        public void setPersonList(List<String> personList) {
            this.personList = personList;
        }
    }

    public static class Wo extends com.x.base.core.project.organization.Identity {
    }

    private List<Wo> list(Business business, Wi wi) throws Exception {
        List<Wo> wos = new ArrayList<>();
        List<String> personMajorIds = new ArrayList<>();
        List<Person> os = business.person().pick(wi.getPersonList());
        List<String> personIds = ListTools.extractProperty(os, JpaObject.id_FIELDNAME, String.class, true, true);
        List<Identity> personMajors = business.identity().listMajorOfPerson(business, personIds);
        if( ListTools.isNotEmpty( personMajors )){
			for( Identity identity : personMajors ){
                personMajorIds.add( identity.getId() );
			}
		}
        EntityManager em = business.entityManagerContainer().get(Identity.class);
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<String> cq = cb.createQuery(String.class);
        Root<Identity> root = cq.from(Identity.class);
        Predicate p = root.get(Identity_.person).in(personIds);
        List<String> identityIds = em.createQuery(cq.select(root.get(Identity_.id)).where(p).distinct(true)).getResultList();
        List<Identity> list = business.identity().pick(identityIds);
        for (Identity o : list) {
        	if( ListTools.contains( personMajorIds, o.getId() )){
				o.setMajor( true );
			}
            wos.add(this.convert(business, o, Wo.class));
        }
        return wos;
    }

}